<?php
namespace Libraries;
use Iterator;
/**
 * 分页类
 * created at 2016-03-25
 * @author 江羿平<jyp@cjkt.com>
 * @package Libraries
 */
class Paginator  implements Iterator{
	  
    /**
     * 指针
     * @var integer
     */
	  protected $position;

    /**
     * 数据数组
     * @var array
     */
    protected $arr;

    /**
     * 总数据量
     * @var integer
     */
    public $total = 0;

    /**
     * 当前数据量
     * @var integer
     */
    public $count = 0;

    /**
     * 最后一页(总页数)
     * @var integer
     */
    public $last_page = 0; 

    /**
     * 上一页
     * @var integer
     */
    public $pre_page  = 0;

    /**
     * 下一页
     * @var integer
     */
    public $next_page = 0;

    /**
     * 当前页
     * @var integer
     */
    public $current_page = 0;

    /**
     * 每页数据量
     * @var integer
     */
    public $page_size = 0;

    /**
     * 页面的链接地址
     * @var integer
     */
    public $url = '';

    /**
     * HTML配置
     * @var array
     */
    public $config = array(
    		'class'=>array(
    			'ul'=>'pagination',
    			'li'=>'',
    			'disabled'=>'disabled',
    			'active'=>'active',
    			'pre'=>'pre_page',
    			'next'=>'next_page',
    			'go-a'=>'go-a',
    			'go-btn'=>'go-btn'

    		),
    		'text'=>array(
    			'pre'=>'«',
    			'next'=>'»',
    			'go-btn'=>'GO'
    		)
    	);

   

    /**
     *构造分页数据     
     *@param integer   $total         总数据量
     *@param integer   $page_size     每页条数
     *@param integer   $current_page  当前页数|NULL
     *@param array     $data          数据
     *@return void
     */
    public function make($total,$page_size,$current_page = NULL,$data = array()){

      $this->arr = $data;
      if(!is_array($this->arr)) $this->arr = array();
      $this->count = count($this->arr);
      $this->total = $total;
      $this->page_size = $page_size>0 ? $page_size : 1;
      $this->current_page = $current_page;
      if(!isset($current_page)) {
        $ci = & get_instance();
        $this->current_page = $ci->input->get('page');
      }else if(!$this->current_page) $this->current_page = 1;

      $this->postion = 0;
      //计算总页数，上一页，下一页
      if($this->total >= $this->page_size){
        $this->last_page = ceil($this->total / $this->page_size);
        if($this->last_page > $this->current_page) {
          $this->next_page = $this->current_page+1;
        }
        if($this->current_page>1){
          $this->pre_page = $this->current_page-1;
        }
      }
    }

  	/**
  	 * 获取分页HTML
  	 *@return string
  	 */
  	public function render(){
  		if($this->last_page<2) return '';
  		if($this->current_page < 1) $this->current_page = 1;
  		if($this->current_page > $this->last_page) $this->current_page = $this->last_page;
  		$html = '<ul class="pagination">';
  		$html .= $this->pre_page_html();
  		//当前页数大于4的时候显示第一页
  		if($this->current_page>6){
  			$html .= $this->page_html(1);
  			$html .= '<li class="'.$this->config['class']['disabled'].'"><span>...</span></li>';
  		}
  		//显示当前页数的前两页
	    $pre_num = 0;
	    $start_inr = 2;
	    if($this->last_page - $this->current_page<2) $start_inr = 4 - $this->last_page + $this->current_page; 
	    for ($i=$start_inr; $i > 0 ; $i--) { 
	    	if($this->current_page > $i){
	    		$html .= $this->page_html($this->current_page-$i);
	    		$pre_num ++;
	    	}
	    }
	    //当前页
	    $html .= $this->page_html($this->current_page);
	    //显示当前页数的后两页
	    $last_p = $this->current_page;
	    if($pre_num > 2) $pre_num = 2;
	    for($i=1; $i < 5-$pre_num;$i++){
	    	if($this->current_page+$i <= $this->last_page){
	    		$html .= $this->page_html($this->current_page+$i);
	    		$last_p = $this->current_page+$i;
	    	}
	    }

	    //当前显示的最大页数小于最大页数时 显示最大页数
	    if($last_p < $this->last_page){
	    	if($last_p<$this->last_page-1) $html .= '<li class="'.$this->config['class']['disabled'].'"><span>...</span></li>';
	    	$html .= $this->page_html($this->last_page);
	    }

	    $html .= $this->next_page_html();
	    //显示跳页按钮
	    if($last_p < $this->last_page){
	    	$html .= '<li><a style="padding:3px 3px" class="'.$this->config['class']['go-a'].'"><input type="text" name="goto-input" style="width:40px"></a></li>';
	    	$html .='<li><a href="javascript:void()" class="'.$this->config['class']['go-btn'].'">'.$this->config['text']['go-btn'].'</a></li>';
		  }
	    $html .=' </ul>';
	    return $html;
  		
  	}

  	/**
  	 *生成url
  	 *@param  integer  $page_num  页数
     *@return string 
  	 */
  	private function create_url($page_num){
  		if($page_num<1) return 'javascript:void(0)';
  		if(!$this->url){
  			$query_string = $_SERVER['QUERY_STRING'];
        $_SERVER['PHP_SELF'] = str_replace('/index.php', '', $_SERVER['PHP_SELF']);
        if(!$query_string) {
          return $_SERVER['PHP_SELF'].'?page='.$page_num;
        }
  			$qs = explode('&', $query_string);
  			$hava_page = false;
  			foreach ($qs as $k=>$v) {
  				if(substr(trim($v),0,5) == 'page='){
  					$qs[$k] = 'page='.$page_num;
  					$hava_page = true;
  				}
  			}
  			if(!$hava_page) $qs[] = 'page='.$page_num;
  			$query_string = implode('&', $qs);
       
  			return $_SERVER['PHP_SELF'].'?'.$query_string;
  		}else{
  			return str_replace('{page}', $page_num, $this->url);
  		}
  	}

  	/**
  	 *上一页HTML
     *@return string
  	 */
  	private function pre_page_html(){
  		$class = $this->pre_page ? 'class="'.$this->config['class']['pre'].'"' : 'class="'.$this->config['class']['disabled'].' '.$this->config['class']['pre'].'"' ;
  		$url = $this->create_url($this->pre_page);
  		return '<li '.$class.'><a href="'.$url.'" aria-label="Previous"><span aria-hidden="true">'.$this->config['text']['pre'].'</span></a></li>';
  	}

  	/**
  	 * 下一页HTML
     *@return string
  	 */
  	private function next_page_html(){
  		$class = $this->next_page ? 'class="'.$this->config['class']['next'].'"' : 'class="'.$this->config['class']['disabled'].' '.$this->config['class']['next'].'"';
  		$url = $this->create_url($this->next_page);
  		return '<li '.$class.'><a href="'.$url.'" aria-label="Next"><span aria-hidden="true">'.$this->config['text']['next'].'</span></a></li>';
  	}

  	/**
  	 * 页面跳转HTML
  	 *@param integer $page_num  页数
     *@return string
  	 */
  	private function page_html($page_num){
  		if($page_num<1) return '';
  		$class = $this->current_page == $page_num ? 'class="'.$this->config['class']['active'].'"' : '';
  		$url = $this->current_page == $page_num ? 'javascript:void(0)' : $this->create_url($page_num);
  		return '<li '.$class.'><a href="'.$url.'">'.$page_num.'</a></li>';
  	}

    /**
     *转换成JSON
     *@return string 
     */
    public function to_json(){
        $json_array = $this->to_array();
        return json_encode($json_array);
    }

    /**
     *转换成数组
     *@return array
     */
    public function to_array(){
        $json_array = array(
          'total' => $this->total,
          'count' => $this->count,
          'last_page' => $this->last_page,
          'pre_page' => $this->pre_page,
          'next_page' => $this->next_page,
          'current_page' => $this->current_page,
          'page_size' => $this->page_size,
          'url' => $this->url,
          'data' => $this->arr
        );
        return $json_array;
    }

    /**
     * 获取分页数据
     * @return array
     */
    public function page_array(){
       $json_array = array(
          'total' => $this->total,
          'count' => $this->count,
          'last_page' => $this->last_page,
          'pre_page' => $this->pre_page,
          'next_page' => $this->next_page,
          'current_page' => $this->current_page,
          'page_size' => $this->page_size
        );
      return $json_array;
    }

    /**
     * 获取数组数据
     * @return array
     */
    public function data(){
      return $this->arr;
    }

    /**
     * 设置指针
     */
    public function rewind(){
        $this->position = 0;
  	}

    /**
     * 验证当前指针是否有数据
     *@return bool
     */
  	public function valid(){
        return isset($this->arr[$this->position]);
  	}

    /** 
     * 获取当前指针
     *@return integer
     */
  	public function key(){
        return $this->position;
  	}

    /**
     * 获取当前数据
     *@return mixed
     */
  	public function current(){
        return $this->arr[$this->position];
  	}

    /**
     * 设置下一指针
     * @return integer
     */
  	public function next(){
        return ++$this->position;
  	}

    /**
     * 获取当前对象
     * @return Paginator
     */
    public function result(){
      return $this;
    }

}